package com.ddpt.platform.common.limit;

import com.ddpt.platform.common.js.JSExpressionParser;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 表达式校验处理类
 */
@Getter
@Setter
public class LimitVerifyProvider {

    private Map<String, BaseLimitCreator<?>> creators = new HashMap<>();

    public void putCreator(String variableName, BaseLimitCreator<?> creator) {
        creators.putIfAbsent(variableName, creator);
    }

    /**
     * 校验表达式
     *
     * @param expression 表达式
     * @return 校验结果
     */
    public boolean verify(String expression) {
        if (StringUtils.isBlank(expression)) {
            return true;
        }
        //最终丢给js引擎的方法参数
        Map<String, Object> parameters = new HashMap<>();
        //最终丢给js引擎的方法名称
        StringBuilder funName = new StringBuilder();

        funName.append("parseExpression(");
        creators.forEach((key, creator) -> {
            //组装方法参数
            funName.append(key).append(",");
            //校验前的通知
            creator.beforeVerify();
            //组装方法参数
            parameters.put(key, creator.getVariables());
        });
        funName.deleteCharAt(funName.length() - 1);
        funName.append(")");

        //js引擎处理表达式
        Object result = JSExpressionParser.doScript(funName.toString(), "return " + expression, parameters);
        if (result == null) {
            return false;
        }
        if (result instanceof Boolean) {
            return (boolean) result;
        }
        return false;
    }

    public boolean ver(String expression) {
        if (StringUtils.isBlank(expression)) {
            return true;
        }
        //最终丢给js引擎的方法参数
        Map<String, Object> parameters = new HashMap<>();
        //最终丢给js引擎的方法名称
        StringBuilder funName = new StringBuilder();
        /*Map<String, List<Integer>> map = new HashMap<>();
        map.put("userGroup", Arrays.asList(521,234));*/

        Map<String, Boolean> map = new HashMap<>();
        // map.put("userGroup_234", true);

        funName.append("parseExpression(");
        funName.append("$_group").append(",");
        parameters.put("$_group", map);
        funName.append("$_system").append(",");
        Map<String, Integer> timeMap = new HashMap<>();
        timeMap.put("weekDay", 1);
        timeMap.put("time", 101000);
        parameters.put("$_system", timeMap);
        funName.deleteCharAt(funName.length() - 1);
        funName.append(")");

        //js引擎处理表达式
        Object result = JSExpressionParser.doScript(funName.toString(), "return " + expression, parameters);
        if (result == null) {
            return false;
        }
        if (result instanceof Boolean) {
            return (boolean) result;
        }
        return false;
    }

    public static void main(String[] args) {
        LimitVerifyProvider provider = new LimitVerifyProvider();
        boolean ver = provider.ver("(((($_system.weekDay==1||$_system.weekDay==3||$_system.weekDay==5||$_system.weekDay==6)&&($_system.time>100000&&$_system.time<110059))) " +
                "&& (!($_group.userGroup_110==true)))");
        System.out.println(ver);
    }
}
